SUCCESS=0
PARAM_ERROR=1
VAR_NOT_FOUND=2
FILE_NOT_FOUND=3



function AssertFunctionResult()
{
    if [ $? != $SUCCESS ]
    then
        echo Function Result Failed!!!
        exit -1
    fi
}

###
# Get configuration variable with os and version number
# $1, Variable name defined in config
# $2, OS name
# $3 [optional], Version number of OS
#
# The variable naming rule in config is:
#     1. VarName_OS_VersionNum
#     2. VarName_OS
#     3. VarName
function GetConfigVar()
{
    if [[ $# < 2 ]]
    then
        echo Incorrect parameters for GetConfigVar!!!
        return $PARAM_ERROR
    fi

    if [[ $# = 3 ]]
    then
        eval var='$'$1_$2_$3
        if [[ -n $var ]]
        then
            echo $var
            return $SUCCESS
        fi
    fi

    eval var='$'$1_$2
    if [[ -n $var ]]
    then
        echo $var
        return $SUCESS
    fi

    eval var='$'$1
    if [[ -n $var ]]
    then
        echo $var
        return $SUCCESS
    fi

    echo No variable in Config: $1!!!
    return $VAR_NOT_FOUND;
}

###
# Get configuration variable array with os and version number
# $1, Variable array name defined in config
# $2, OS name
# $3 [optional], Version number of OS
#
# The variable naming rule in config is:
#     1. VarName_OS_VersionNum
#     2. VarName_OS
#     3. VarName
function GetConfigArray()
{
    arrayName=$(GetConfigVar $@)
    result=$?
    if [ $result = $SUCCESS ]
    then
        eval echo '${'$arrayName'[@]}'
    else
        echo $arrayName
    fi

    return $result
}

###
# Break for manually check
# $1 true for check and false for ignore
function WaitForCheck()
{
    if [ $# = 1 ]
    then
        if [ $1 = true ]
        then
            waitForCheck=true
        else
            waitForCheck=false
        fi
    else
        waitForCheck=false
    fi

    if [ $waitForCheck = true ]
    then
        read -p "Press ENTER to continue ..." tmp
        echo
    fi
}

function GetYUMConfPath()
{
    yumConf=/etc/yum.conf
    if [ -f $yumConf ]
    then
        echo $yumConf
    else
        return $FILE_NOT_FOUND
    fi

    return $SUCCESS
}

function GetDNFConfPath()
{
    dnfConf=/etc/dnf/dnf.conf
    if [ -f $dnfConf ]
    then
        echo $dnfConf
    else
        return $FILE_NOT_FOUND
    fi

    return $SUCCESS
}

function GetAPTConfPath()
{
    aptConf=/etc/apt/apt.conf.d
    if [ -d $aptConf ]
    then
        echo $aptConf
    else
        return $FILE_NOT_FOUND
    fi

    return $SUCCESS
}

function GetVSFTPConfPath()
{
    ftpConf=/etc/vsftpd.conf
    if [ -f $ftpConf ]
    then
        echo $ftpConf
        return $SUCCESS
    fi

    # CentOS
    ftpConf=/etc/vsftpd/vsftpd.conf
    if [ -f $ftpConf ]
    then
        echo $ftpConf
        return $SUCCESS
    fi

    return $FILE_NOT_FOUND
}

function GetFTPUsersPath()
{
    ftpusers=/etc/ftpusers
    if [ -f $ftpusers ]
    then
        echo $ftpusers
        return $SUCCESS
    fi

    ftpusers=/etc/vsftpd/ftpusers
    if [ -f $ftpusers ]
    then
        echo $ftpusers
        return $SUCCESS
    fi

    return $FILE_NOT_FOUND
}

function GetMySQLDPath()
{
    mysqldPath=/usr/bin/mysqld
    if [ -f $mysqldPath ]
    then
        echo $mysqldPath
        return $SUCCESS
    fi
    mysqldPath=/usr/sbin/mysqld
    if [ -f $mysqldPath ]
    then
        echo $mysqldPath
        return $SUCCESS
    fi

    return $FILE_NOT_FOUND
}

function GetMySQLPath()
{
    mysqlPath=/usr/bin/mysql
    if [ -f $mysqlPath ]
    then
        echo $mysqlPath
        return $SUCCESS
    fi

    return $FILE_NOT_FOUND
}

function GetMySQLLogPath()
{
    mysqlLogPath=/var/log/mysql/mysqld.log
    if [ -f $mysqlLogPath ]
    then
        echo $mysqlLogPath
        return $SUCCESS
    fi

    return $FILE_NOT_FOUND
}

function Get7zCmd()
{
    cmdPath=/usr/bin/7z
    if [ -f $cmdPath ]
    then
        echo $cmdPath
        return $SUCCESS
    fi
    cmdPath=/usr/bin/7za
    if [ -f $cmdPath ]
    then
        echo $cmdPath
        return $SUCCESS
    fi

    return $FILE_NOT_FOUND
}

###
# Configure proxy for apt or dnf
function ConfigureProxy()
{
    echo Configure Proxy:

    read -p "Input proxy (e.g. http://xxx.xx.xxx.xx:8080):" proxy

    yumConf=$(GetYUMConfPath)
    if [ $? == $SUCCESS ]
    then
        read -p "Input proxy username: " username
        read -p "Input proxy password: " password
        echo proxy=$proxy | tee -a $yumConf
        echo proxy_username=$username | tee -a $yumConf
        echo proxy_password=$password | tee -a $yumConf
    fi

    dnfConf=$(GetDNFConfPath)
    if [ $? == $SUCCESS ]
    then
        read -p "Input proxy username: " username
        read -p "Input proxy password: " password
        echo proxy=$proxy | tee -a $dnfConf
        echo proxy_username=$username | tee -a $dnfConf
        echo proxy_password=$password | tee -a $dnfConf
    fi

    aptConf=$(GetAPTConfPath)
    if [ $? == $SUCCESS ]
    then
        touch $aptConf/66vmproxy
        echo "Acquire::http::proxy \"$proxy\";" | tee -a $aptConf/66vmproxy
        apt update
    fi

    echo
}

###
# Add user and group and make user folder in /home
# if $# = 1, add user $1 and group $1
# if $# = 2, add user $1 and group $2
function AddUser()
{
    echo Add User:

    if [ $# = 1 ]
    then
        user=$1
        grp=$1
    elif [ $# = 2 ]
    then
        user=$1
        grp=$2
    else
        echo No correct user and group defined for AddUser!!!
        echo
        return
    fi

    echo Add user $user and group $grp

# Before ubuntu 24.04
#    groupadd $grp
#    useradd -d /home/$user -g $grp $user
#
#    echo Now may need to input new user password:
#    passwd $user

# Since ubuntu 24.04
    addgroup $grp
    adduser --home /home/$user -ingroup $grp $user
    
    echo
}

###
# Update installation App source list
# $1=install app
function UpdateInstallAppSource()
{
    echo Update Install App Source:

    if [ $# = 1 ]
    then
        installApp=$1
    else
        echo Invalid install app name!!!
        echo
        return
    fi

    if [ $installApp = apt ]
    then
        $installApp update
    fi

    echo
}

###
# Install application
# $1=install app
# $2=appName
function InstallUtil()
{
    echo Install Utility:

    if [ $# = 2 ]
    then
        cmd=$1
        util=$2
    else
        echo Invalid apt cmd and utility name!!!
        echo
        return
    fi

    echo $cmd install $util
    $cmd install $util
    
    echo 
}

###
# Configure vsftp after installation
# $@=All other new users should deny access
function ConfigureFTP()
{
    echo Configure FTP:

    #
    # vsftp configure
    #

    # Debian
    ftpConf=$(GetVSFTPConfPath)
    if [ $? != $SUCCESS ]
    then
       echo VSFTP is not installed yet!!!
       echo
       return
    fi
    sed -i -e 's/#write_enable=YES/write_enable=YES/' -e 's/#local_umask=022/local_umask=022/' -e 's/#chroot_local_user=YES/chroot_local_user=YES/' $ftpConf
    echo allow_writeable_chroot=YES | tee -a $ftpConf

    #
    # Deny user access
    #

    # Debian
    ftpusers=$(GetFTPUsersPath)
    if [ $? != $SUCCESS ]
    then
        echo ftpusers is not there yet!!!
        echo
        return
    fi

    for i in $@
    do
        echo $i | tee -a $ftpusers
    done

    echo
}

###
# Configure Emacs after installation
function ConfigureEmacs()
{
    echo Configure Emacs:

    cd

    bashrc=~/.bashrc
    if [ ! -f $bashrc ]
    then
        touch $bashrc
    fi
    echo "alias emacs='emacs -nw'" | tee -a ${bashrc}

    emacsrc=~/.emacs
    if [ ! -f $emacsrc ]
    then
        touch $emacsrc
    fi
    echo "(require 'linum)" | tee -a ${emacsrc}
    echo "(global-linum-mode 1)" | tee -a ${emacsrc}
    echo "(setq linum-format \"%4d \\u2502\")" | tee -a ${emacsrc}
    echo "(setq c-basic-offset 4)" | tee -a ${emacsrc}
    echo "(setq-default indent-tabs-mode nil)" | tee -a ${emacsrc}
    echo "(require 'package)" | tee -a ${emacsrc}
    echo "(add-to-list 'package-archives '(\"melpa\" . \"https://melpa.org/packages/\") t)" | tee -a ${emacsrc}
    echo "(package-initialize)" | tee -a ${emacsrc}
    
    echo
}

###
# Configure git after installation
# $1 $mail
# $2 $user
# $3 $isConfigureProxy
function ConfigureGit()
{
    echo Configure Git:

    if [ $# = 3 ]
    then
        mail=$1
        user=$2
    else
        echo Invalid git configure parameter!!!
        echo
        return
    fi

    git config --global user.email "$mail"
    git config --global user.name "$user"

    if [ $3 = true ]
    then
        read -p "Input proxy for git (e.g. http://xxx.xx.xxx.xx:8080):" proxy
        git config --global http.proxy $proxy
    fi

    echo
}

###
# Create folders in user home
# $1 folder name under home
function CreateFolderInHome()
{
    echo Create Folder:

    if [ $# = 1 ]
    then
        fld=$1
    else
        echo Invalid folder passed in!!!
    fi

    cd ~
    if [ -d $fld ]
    then
        echo $fld already exists!
    else
        mkdir $fld
        echo Create new folder: $fld
    fi

    echo
}

###
# Clean userless folders not in home folder list
# $@ home folder list
function CleanHomeFolder()
{
    echo Clean Home Folder:

    cd ~
    allFolders=(`ls`)
    homeFolders=(`echo $@`)
    for((i=0; i<${#allFolders[@]}; i++))
    do
        if [ -d ${allFolders[${i}]} ]
        then
            isFound=false
            for((j=0; j<${#homeFolders[@]}; j++))
            do
                if [[ ${allFolders[${i}]} = ${homeFolders[${j}]} ]]
                then
                    isFound=true
                fi
            done
            if [ $isFound = false ]
            then
                echo Remove folder: ${allFolders[${i}]}
                rm ${allFolders[${i}]} -rf
            fi
        fi
    done

    echo
}

###
# Use vsftp to download package to current folder
# $1 ftp command
# $2 user name to login ftp
# $3 ip address of ftp server
# $4 path of file to be downloaded in ftp server
function FTPGet()
{
    echo FTP Get:

    if [ $# = 4 ]
    then
        ftp=$1
        user=$2
        ip=$3
        path=$4

	echo Get by FTP: $path
    else
        echo Invalid FTP input parameters!!!
        echo
        return
    fi

    echo get $path | $ftp $user@$ip

    echo
}

###
# $1 zip file path
# $2 unzip destination
#
# return - upzip path
function ExtractFile()
{
    if [ $# = 2 ]
    then
        zip=$1
        dest=$2
    else
        echo Invalid parameter for extract file!!!
        return $PARAM_ERROR
    fi
    if [ ! -f $zip ]
    then
        echo Extract file $zip not exist!!!
        return $FILE_NOT_FOUND
    fi
    if [ ! -d $dest ]
    then
        echo Extract destination $dest not exist!!!
        return $FILE_NOT_FOUND
    fi

    zipName=${zip##*/}
    if [[ $zipName =~ .tar.gz$ ]]
    then
        unzipName=${zipName%.tar.gz}
        tar xzvf $zip -C $dest >&2
    elif [[ $zipName =~ .tar.bz2$ ]]
    then
        unzipName=${zipName%.tar.bz2}
        tar xjvf $zip -C $dest >&2
    elif [[ $zipName =~ .7z$ ]]
    then
        unzipName=${zipName%.7z}
        7z x $zip -o${dest} >&2
    else
        echo No Match Format: ${zipName}!!!
        return $PARAM_ERROR
    fi

    echo $dest/$unzipName
    return $SUCCESS
}

###
# Standard make install process in package folder
# $1 package path
# $2 configure option
function MakeInstallPackage()
{
    echo Install Package:

    if [ $# = 1 ]
    then
        pkg=$1
        config=
    elif [ $# = 2 ]
    then
        pkg=$1
        config=$2
    else
        echo Invalid package parameter!!!
        echo
        return
    fi

    if [ ! -d $pkg ]
    then
        echo Invalid package path to install!!!
        echo
        return
    fi

    cd $pkg
    if [ -f configure ]
    then
        cmdConfig=configure
    elif [ -f config ]
    then
        cmdConfig=config
    else
        echo No configure file available!!!
        echo
        return
    fi
    ./$cmdConfig $config
    make
    make install

    echo
}
